-
Notifications
You must be signed in to change notification settings - Fork 22
lazy_import as a context manager #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This approach looks simple, and I like the syntax. I am not familiar with meta path, though. Is this a standard, supported mechanism? @tlambert03 may also be interested. Can you please make a PR that doesn't take out all the old code, but adds this as a new function? That'd make the diff easier to review. |
I had never heard of According to PEP 451, which introduced ModuleSpecs in Python 3.4, it seems |
It injects LazyFinder to sys.meta_path, which searches ModuleSpecs with the rest of sys.meta_path's Finders, and wraps the result in importlib.util.LazyLoader, which defers loading until first access.
ac85913
to
4b985f4
Compare
Done! *Well, more or less. If you want to keep the old code, I should also leave the previous tests. |
I like the syntax too! but are you sure it's lazy? I just checked out this PR, installed it, and created the following test case:
where print("IMPORT")
def some_func(x: int) -> int:
return x + 1
|
I do think that adding a |
I think this is because it's actually eagerly importing? |
But You need to do: import lazy_loader
with lazy_loader.lazy_import():
import mod # lazy
mod.some_func # triggers import as in the examples where you used |
The import system seems to be divided in finding and loading. As it doesn't find the module, it can raise an eager |
I'm a bit confused... in the current implement of lazy.attach, the goal is to be able to do something like:
or ... another example taken from SPEC 1: import skimage as ski # cheap operation; does not load submodules
ski.filters # cheap operation; loads the filters submodule, but not
# any of its submodules or functions
ski.filters.gaussian(...) # loads the file in which gaussian is implemented
# and calls that function are you suggesting that it would be and in your example, how would you declare what the public exports are? |
Ok, now I understand that that test. Yes, you're right. What I did is different to SPEC 1, and only works for modules, but not for exported functions. For instance, if from lazy_loader import lazy_import
with lazy_import():
from . import filters, morphology, ... it would lazily export all those subpackages. And then, you could do: import skimage as ski # cheap; does not load submodules
skimage.filters # only loads the filters submodule where But So, in conclusion, it does not replace |
yep, that jives with my understanding of what it's doing |
Thanks all, that's a helpful discussion. I'm going to close this for now, as it does not cover the intent of the SPEC, but of course this remains a cool trick that libraries could use internally. Thanks for participating, @maurosilber, much appreciated! |
Hi!
I tried a different approach to solve this problem,
which defers a standard import statement inside a context manager.
Usage:
Advantages:
ImportError
if a module is not found,I'm not sure if it is missing some functionality that the current version of
lazy_loader
has.How it works:
It injects LazyFinder to sys.meta_path, which searches with the rest of sys.meta_path's Finders.
If it found one, it wraps the resulting ModuleSpec in importlib.util.LazyLoader, which defers loading until first access.
I hope you can check it out!